package base

import (
	"fmt"
	"strconv"
	"zinx/interfa"
	"zinx/utils"
	"zinx/zlog"
)

type MsgHandle struct {
	Apis           map[uint32]*Router      // 存放每个MsgID 所对应的处理方法的切片
	WorkerPoolSize uint32                  // 业务工作Worker池的数量
	TaskQueue      []chan interfa.IRequest //Worker负责取任务的消息队列
}

func NewMsgHandle() *MsgHandle {
	return &MsgHandle{
		Apis:           make(map[uint32]*Router),
		WorkerPoolSize: utils.GlobalObject.WorkerPoolSize,
		TaskQueue:      make([]chan interfa.IRequest, utils.GlobalObject.WorkerPoolSize), //一个消息队列对应一个worker池子
	}
}

func (this *MsgHandle) SendMsgToTaskQueue(request interfa.IRequest) {
	// 得到需要处理此条连接的workerID
	workerID := request.GetConnection().GetConnID() % this.WorkerPoolSize
	// 将消息放到管道中
	this.TaskQueue[workerID] <- request
}

func (this *MsgHandle) DoMsgHandler(request interfa.IRequest) {
	router, ok := this.Apis[request.GetMsgID()]
	if !ok {
		fmt.Println("no find Router In Apis")
		return
	}
	router.Reindx()
	router.Next(request)
}

func (this *MsgHandle) AddRouter(msgId uint32, handler ...interfa.RouterHandler) {
	if _, ok := this.Apis[msgId]; ok {
		zlog.Error("Repeated Api, MsgId = ", strconv.Itoa(int(msgId)))
		panic("Repeated Api, MsgId = " + strconv.Itoa(int(msgId)))
	}
	this.Apis[msgId] = &Router{}
	this.Apis[msgId].Reset()
	this.Apis[msgId].AddHandler(handler...)
	zlog.Debug("AddRouter MsgId", msgId, " Successful")
}

// 10个 Goroutine
func (this *MsgHandle) StartOneWorker(workerID int, tarkQueue chan interfa.IRequest) {
	for {
		select {
		case request := <-tarkQueue:
			this.DoMsgHandler(request) // 调用钩子函数
		}
	}
}

func (this *MsgHandle) StartWorkerPool() {
	for i := 0; i < int(this.WorkerPoolSize); i++ {
		this.TaskQueue[i] = make(chan interfa.IRequest, utils.GlobalObject.MaxWorkerTaskLen)
		zlog.Debug("Start ", i+1, " Worker Coroutine Successful")
		go this.StartOneWorker(i, this.TaskQueue[i])
	}
}
